//
// Created by martin on 3/14/22.
//

#include <memory>
#include <stdio.h>
#include <functional>

using namespace std;

class A
{
public:
    A(int val) : val_(val) { }
    void func()
    {
        printf("A val_ = %d\n", val_);
    }

private:
    int val_;
};

class Foo
{
public:
    void f1(const shared_ptr<A>& p)
    {
        printf("Foo::Foo p.use_count = %ld\n", p.use_count());
        std::bind(&A::func, p);
        printf("Foo::Foo p.use_count = %ld\n", p.use_count());
    }

//    void func()
//    {
//        printf("func\n");
//    }
};

void test1(shared_ptr<int>& p)
{
    printf("test1 pi.use_count = %ld\n", p.use_count());
}

int main()
{
    shared_ptr<int> pi = make_shared<int>(10);
    printf("main pi.use_count = %ld\n", pi.use_count());
    test1(pi);

    shared_ptr<A> pa = make_shared<A>(20);
    shared_ptr<Foo> pf = make_shared<Foo>();
    pf->f1(pa);
    printf("main pa.use_count = %ld\n", pa.use_count());

    weak_ptr<int> wpi = pi;
    printf("pi.use_count = %ld\n", pi.use_count());
    shared_ptr<int> guard;
    guard = wpi.lock();
    if (guard)
    {
        printf("guard pi.use_count = %ld\n", pi.use_count());
    }

    return 0;
}
